import 'package:top_foundation/top_foundation.dart';

import 'net_code.dart';

class NetReponse {
  final int code;
  final String msg;
  String? message;
  int? status;
  final dynamic data;
  final Map<String, dynamic> json;

  bool get isSuccess {
    return code == 0;
  }

  NetReponse({
    required this.code,
    required this.msg,
    this.message,
    this.data,
    this.status,
    required this.json,
  });

  factory NetReponse.fromJson(Map<String, dynamic> json) =>
      _$NetReponseFromJson(json);
}

NetReponse _$NetReponseFromJson(Map<String, dynamic> json) => NetReponse(
    json: json,
    code: int.tryParse(json['code'].toString()) ?? 999,
    msg: json['msg'] as String? ?? '',
    message: json['message'] as String?,
    data: json['data'],
    status: numVal(json['status']).toInt());

class NetBaseReponse<T> {
  String msg = '';
  int? status;
  T? data;
  List<T>? list;
  late NetResponseCode code;
  late Map<String, dynamic> json;

  bool get isSuccess {
    return code == NetResponseCode.success;
  }

  void _initResponse(
    NetReponse res, {
    T Function(Map<String, dynamic> json)? fromJsonT,
  }) {
    json = res.json;
    status = res.status;
    if (fromJsonT != null) {
      if (res.data is Map) {
        data = fromJsonT(res.data);
      } else if (res.data is List) {
        var d = res.data as List;
        list = d.map((e) => fromJsonT(e)).toList();
      }
    } else {
      data = res.data;
    }
    msg = res.message ?? res.msg;
    if (status == 10002 || res.message == '501') {
      code = NetResponseCode.invalidToken;
    } else if (res.code == 0 || res.status == 200) {
      code = NetResponseCode.success;
    } else if (res.status == 401) {
      //token 失效 清除token
      code = NetResponseCode.invalidToken;
      msg = '登录失效';
    } else {
      switch (res.code) {
        case 401:
          //token 失效 清除token
          code = NetResponseCode.invalidToken;
          msg = '登录失效';
          break;
        default:
          code = NetResponseCode.unknow;
          if (msg.isEmpty) {
            msg = '未知错误';
          }
          break;
      }
    }
  }

  NetBaseReponse.response({
    required NetReponse res,
    T Function(Map<String, dynamic> json)? fromJsonT,
  }) {
    _initResponse(res, fromJsonT: fromJsonT);
  }
  NetBaseReponse.code({required this.code}) {
    if (code == NetResponseCode.networkError) {
      msg = '网络异常，请重试';
    }
  }
  NetBaseReponse.origin({required this.json}) {
    var res = NetReponse.fromJson(json);
    _initResponse(res);
  }
}

class PageModel<T> {
  int current;
  int total;
  int size;
  int pages;
  List<T>? records;

  bool get hasNext {
    return pages > current;
  }

  PageModel({
    this.current = 1,
    this.total = 1,
    this.size = 10,
    this.pages = 1,
    this.records,
  });

  /// json 整个data
  /// fromJsonT 数据内部列表解析
  /// listKey 当内部列表key 不是默认records时，可自定义
  factory PageModel.fromJson(
    Map<String, dynamic> json,
    T Function(Map<String, dynamic> json) fromJsonT, {
    String currentKey = 'current',
    String listKey = 'records',
    String pageKey = 'pages',
  }) =>
      PageModel<T>(
        current: json[currentKey] as int? ?? 1,
        total: json['total'] as int? ?? 1,
        size: json['size'] as int? ?? 1,
        pages: json['pages'] as int? ?? 1,
        records: (json[listKey] as List?)
            ?.map(
              (e) => fromJsonT(e),
            )
            .toList(),
      );

  IndicatorResult update(NetBaseReponse res) {
    if (res.data is! PageModel) {
      return IndicatorResult.fail;
    }
    if (res.isSuccess) {
      PageModel page = res.data!;
      current = page.current;
      total = page.total;
      size = page.size;
      pages = page.pages;

      if (page.current > 1) {
        records?.addAll(page.records as List<T>? ?? []);
      } else {
        records = page.records as List<T>?;
      }
      if (page.hasNext) {
        return IndicatorResult.success;
      } else {
        return IndicatorResult.noMore;
      }
    }
    return IndicatorResult.fail;
  }

  void reset() {
    records = null;
    current = 1;
  }
}
